$OpenBSD: patch-server_wconvert_c,v 1.1 2003/03/12 21:21:55 brad Exp $
--- server/wconvert.c.orig	Wed Nov 27 02:27:28 1996
+++ server/wconvert.c	Wed Mar 12 14:59:07 2003
@@ -101,4 +101,5 @@ extern reqproc ExtensionWideVector[];
 
 extern void DispDebug() ;
+extern const Ushort *ushortmemchr pro((const Ushort *, int, size_t));
 extern int canna_server_hi ;
 extern int canna_server_lo ;
@@ -1323,5 +1324,8 @@ ClientPtr *clientp ;
     int cxnum = Request.type18.context, stat = -1;
     int requestsize = Request.type18.size, retval;
+    size_t datasize = Request.type18.datalen - SIZEOFSHORT * 2;
 
+    if (datasize == 0 || req->data[datasize - 1] != 0)
+      goto protoerr;
     if (validcontext(cxnum, client, wListDictionary)) {
       if (requestsize <= sizeof(local_buffer) ||
@@ -1360,4 +1364,5 @@ ClientPtr *clientp ;
     }	
 
+protoerr:
     retval = SendType6Reply(client, wListDictionary, EXTPROTO, stat,
 			    dicnames, namesize(dicnames, stat));
@@ -1471,8 +1476,13 @@ ClientPtr *clientp ;
     int cxnum = Request.type18.context, stat = BADCONT;
     int dirlen, requestsize = Request.type18.size, retval;
+    size_t datasize = Request.type18.datalen - SIZEOFSHORT * 2;
 
+    if (datasize == 0 || req->data[datasize - 1] != 0)
+      goto protoerr;
     if (validcontext(cxnum, client, wGetWordTextDictionary)) {
 	dirname = req->data ;
 	dirlen = strlen(dirname) + 1 ;
+	if (dirlen == datasize)
+	  goto protoerr;
 	dicname = &(req->data[dirlen]) ;
 	if (dirlen > 1) {
@@ -1516,4 +1526,5 @@ ClientPtr *clientp ;
 	}
     }
+protoerr:
     retval = SendType7Reply(client, wGetWordTextDictionary, EXTPROTO,
 			    stat, stat > 0 ? stat + 1 : 0, infobuf);
@@ -2097,10 +2108,10 @@ ClientPtr *clientp;
 
   if (validcontext(cxnum, client, wThrough)) {
-    buf = malloc((int)Request.type20.bufsize);
+    content_size = Request.type20.datalen - (SIZEOFINT * 2 + SIZEOFSHORT);
+    buf = malloc(content_size);
     if (buf) {
-      content_size = Request.type20.datalen - (SIZEOFINT * 2 + SIZEOFSHORT);
       bcopy(Request.type20.buf, buf, content_size);
       stat = size = RkThrough(cxnum, Request.type20.command,
-			      buf, content_size, (int)Request.type20.bufsize);
+			      buf, content_size, content_size);
     }
   }
@@ -2297,4 +2308,7 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq1 start!!\n") );
 
+    if (Request.type1.datalen != 0)
+	return( -1 );
+
     return( 0 ) ;
 }
@@ -2306,4 +2320,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq2 start!!\n") );
 
+    if (Request.type2.datalen != SIZEOFSHORT)
+	return( -1 );
     buf += HEADER_SIZE; Request.type2.context = S2TOS(buf);
     ir_debug( Dmsg(10, "req->context =%d\n", Request.type2.context) );
@@ -2318,4 +2334,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq3 start!!\n") );
 
+    if (Request.type3.datalen != SIZEOFSHORT * 2)
+	return( -1 );
     buf += HEADER_SIZE; Request.type3.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type3.buflen = S2TOS(buf);
@@ -2335,4 +2353,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq4 start!!\n") );
 
+    if (Request.type4.datalen < SIZEOFSHORT * 4)
+	return( -1 );
     buf += HEADER_SIZE; Request.type4.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type4.begin = S2TOS(buf);
@@ -2340,5 +2360,9 @@ BYTE *buf ;
     buf += SIZEOFSHORT; Request.type4.yomilen = S2TOS(buf);
     Request.type4.yomi = (Ushort *)(buf += SIZEOFSHORT) ;
-    len = Request.type4.datalen - SIZEOFSHORT * 4;
+    len = Request.type4.yomilen + 1;
+    if (Request.type4.datalen != SIZEOFSHORT * (4 + len)
+	    || len == 0
+	    || Request.type4.yomi[len - 1] != 0)
+	return( -1 );
     for (data = Request.type4.yomi, i = 0; i < len; i++, data++)
 	*data = ntohs((unsigned short)*data); /* ����äȤ���ʤ� */
@@ -2360,4 +2384,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq5 start!!\n") );
 
+    if (Request.type5.datalen != SIZEOFSHORT * 2 + SIZEOFINT)
+	return( -1 );
     buf += HEADER_SIZE; Request.type5.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type5.size = S2TOS(buf);
@@ -2376,4 +2402,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq6 start!!\n") );
 
+    if (Request.type6.datalen != SIZEOFSHORT * 3)
+	return( -1 );
     buf += HEADER_SIZE; Request.type6.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type6.number = S2TOS(buf);
@@ -2392,4 +2420,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq7 start!!\n") );
 
+    if (Request.type7.datalen != SIZEOFSHORT * 3)
+	return( -1 );
     buf += HEADER_SIZE; Request.type7.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type7.number = S2TOS(buf);
@@ -2408,4 +2438,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq8 start!!\n") );
 
+    if (Request.type8.datalen != SIZEOFSHORT * 4)
+	return( -1 );
     buf += HEADER_SIZE; Request.type8.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type8.curbun = S2TOS(buf);
@@ -2426,4 +2458,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq9 start!!\n") );
 
+    if (Request.type9.datalen != SIZEOFSHORT * 4)
+	return( -1 );
     buf += HEADER_SIZE; Request.type9.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type9.number = S2TOS(buf);
@@ -2443,7 +2477,11 @@ BYTE *buf ;
 {
     register int i ;
+    int rest;
 
     ir_debug( Dmsg(10, "ProcWideReq10 start!!\n") );
 
+    rest = Request.type10.datalen - (SIZEOFSHORT * 2 + SIZEOFINT);
+    if (rest < 0)
+	return( -1 );
     buf += HEADER_SIZE; Request.type10.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type10.number = S2TOS(buf);
@@ -2453,4 +2491,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "req->mode =%d\n", Request.type10.mode) );
 
+    if (rest != Request.type10.number * SIZEOFSHORT)
+	return( -1 );
     buf += SIZEOFINT; Request.type10.kouho = (short *)buf; /* short? */
     for (i = 0; i < Request.type10.number; i++) {
@@ -2469,10 +2509,16 @@ BYTE *buf ;
     int i, len ;
 
-    ir_debug( Dmsg(10, "ProcWideReq10 start!!\n") );
+    ir_debug( Dmsg(10, "ProcWideReq11 start!!\n") );
 
+    if (Request.type11.datalen < SIZEOFSHORT * 2)
+	return( -1 );
     buf += HEADER_SIZE; Request.type11.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type11.curbun = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type11.yomi = (Ushort *)buf;
+    if (Request.type11.datalen % SIZEOFSHORT != 0)
+	return( -1 );
     len = ((int)Request.type11.datalen - SIZEOFSHORT * 2) / SIZEOFSHORT ;
+    if (len == 0 || Request.type11.yomi[len - 1] != 0)
+	return( -1 );
     for (data = Request.type11.yomi, i = 0; i < len; i++, data++)
 	*data = ntohs( *data ); /* �ʤ󤫤�� */
@@ -2491,14 +2537,24 @@ BYTE *buf ;
 {
     register Ushort *data;
-    int i, len ;
+    int i, len, rest;
 
     ir_debug( Dmsg(10, "ProcWideReq12 start!!\n") );
 
+    rest = Request.type12.datalen - SIZEOFSHORT;
+    if (rest < 0)
+	return( -1 );
     buf += HEADER_SIZE; Request.type12.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type12.datainfo = (Ushort *)buf;
+    if (!ushortmemchr((Ushort *)buf, 0, rest / SIZEOFSHORT))
+	return( -1 );
     len = ushortstrlen((Ushort *)buf) + 1;
+    rest -= len * SIZEOFSHORT;
+    if (rest <= 0)
+	return( -1 );
     for( data = Request.type12.datainfo, i = 0; i < len; i++, data++ )
 	*data = ntohs( *data ); /* �ʤ󤫤�� */
     buf += len * SIZEOFSHORT;
+    if (buf[rest - 1] != '\0')
+	return( -1 );
     Request.type12.dicname = (char *)buf;
     ir_debug( Dmsg(10, "req->context =%d\n", Request.type12.context) );
@@ -2518,22 +2574,35 @@ BYTE *buf ;
 {
     register Ushort *data;
-    int i ,len ;
+    int i ,len, rest;
 
     ir_debug( Dmsg(10, "ProcWideReq13 start!!\n") );
 
+    rest = Request.type13.datalen - SIZEOFSHORT;
+    if (rest < 0)
+	return( -1 );
     buf += HEADER_SIZE; Request.type13.context = S2TOS(buf);
     len = SIZEOFSHORT ;
     buf += len;
     Request.type13.dicname = (char *)buf;
+    if (!memchr(buf, 0, rest))
+	return( -1 );
     len = strlen( (char *)buf ) + 1;
+    rest -= len;
+    if (rest % SIZEOFSHORT
+	    || rest < SIZEOFSHORT * 3)
+	return( -1 );
     buf += len;
     Request.type13.yomi = (Ushort *)buf;
     len = ((int)Request.type13.datalen - len - SIZEOFSHORT * 4) / SIZEOFSHORT;
+    if (ushortmemchr((Ushort *)buf, 0, len) != (Ushort *)buf + len - 1)
+	return( -1 );
     for( data = Request.type13.yomi, i = 0; i < len; i++, data++)
 	*data = ntohs( *data );
-    buf += (ushortstrlen((Ushort *)buf) + 1) * SIZEOFSHORT;
+    buf += len * SIZEOFSHORT;
     Request.type13.yomilen = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type13.kouhosize = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type13.hinshisize = S2TOS(buf);
+    if (Request.type13.yomilen != len - 1)
+	return( -1 );
     ir_debug( Dmsg(10, "req->context =%d\n", Request.type13.context) );
     ir_debug( Dmsg(10, "req->dicname =%s\n", Request.type13.dicname) );
@@ -2557,4 +2626,7 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq14 start!!\n") );
 
+    if (Request.type14.datalen <= SIZEOFINT + SIZEOFSHORT
+	    || Request.type14.datalen % SIZEOFSHORT)
+	return( -1 );
     buf += HEADER_SIZE; Request.type14.mode = L4TOL(buf);
     buf += SIZEOFINT;   Request.type14.context = S2TOS(buf);
@@ -2562,4 +2634,6 @@ BYTE *buf ;
     len = ((int)Request.type14.datalen - SIZEOFSHORT - SIZEOFINT)
       / SIZEOFSHORT;
+    if (Request.type14.yomi[len - 1] != 0)
+	return( -1 );
     for (data = Request.type14.yomi, i = 0; i < len; i++, data++)
 	*data = ntohs( *data ); /* �ʤ󤫤�� */
@@ -2578,9 +2652,15 @@ ProcWideReq15(buf)
 BYTE *buf ;
 {
+    int rest;
     ir_debug( Dmsg(10, "ProcWideReq15 start!!\n") );
 
+    rest = Request.type15.datalen - (SIZEOFINT + SIZEOFSHORT);
+    if (rest <= 0)
+	return( -1 );
     buf += HEADER_SIZE; Request.type15.mode = L4TOL(buf);
     buf += SIZEOFINT;   Request.type15.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type15.dicname = (char *)buf;
+    if (buf[rest - 1] != 0)
+	return( -1 );
     ir_debug( Dmsg(10, "req->mode =%d\n", Request.type15.mode) );
     ir_debug( Dmsg(10, "req->context =%d\n", Request.type15.context) );
@@ -2598,4 +2678,7 @@ BYTE *buf ;
 
     buf += HEADER_SIZE;
+    if (Request.type17.datalen < SIZEOFCHAR * 2
+	    || buf[Request.type17.datalen - SIZEOFCHAR * 2] != 0)
+	return( -1 );
     Request.type17.dicname = (char *)buf;
     Request.type17.mode = (char)*(buf + Request.type17.datalen - SIZEOFCHAR) ;
@@ -2614,4 +2697,6 @@ BYTE *buf ;
     ir_debug( Dmsg(10, "ProcWideReq18 start!!\n") );
 
+    if (Request.type18.datalen < SIZEOFSHORT * 2)
+	return( -1 );
     buf += HEADER_SIZE; Request.type18.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type18.data = (char *)buf;
@@ -2631,10 +2716,16 @@ ProcWideReq19(buf)
 BYTE *buf ;
 {
+    int rest;
     ir_debug( Dmsg(10, "ProcWideReq19 start!!\n") );
 
+    rest = Request.type20.datalen - (SIZEOFSHORT + SIZEOFINT * 2);
+    if (rest < 0)
+	return( -1 );
     buf += HEADER_SIZE; Request.type20.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type20.command = L4TOL(buf);
     buf += SIZEOFINT;   Request.type20.bufsize = L4TOL(buf);
     buf += SIZEOFINT;   Request.type20.buf = (char *)buf;
+    if (Request.type20.bufsize != rest)
+	return( -1 );
     ir_debug( Dmsg(10, "req->context =%d\n", Request.type20.context) );
     ir_debug( Dmsg(10, "req->command =%d\n", Request.type20.command) );
@@ -2648,13 +2739,23 @@ ProcWideReq20(buf)
 BYTE *buf ;
 {
+    BYTE *bufend;
     ir_debug( Dmsg(10, "ProcWideReq20 start!!\n") );
 
+    if (Request.type21.datalen < SIZEOFINT + SIZEOFSHORT)
+	return( -1 );
     buf += HEADER_SIZE; Request.type21.mode = L4TOL(buf);
+    bufend = buf + Request.type21.datalen;
     buf += SIZEOFINT;   Request.type21.context = S2TOS(buf);
     buf += SIZEOFSHORT; Request.type21.dirname = (char *)buf;
+    if (!memchr(buf, 0, bufend - buf))
+	return( -1 );
     buf += strlen((char *)buf) + 1;
     Request.type21.srcdic = (char *)buf;
+    if (!memchr(buf, 0, bufend - buf))
+	return( -1 );
     buf += strlen((char *)buf) + 1;
     Request.type21.dstdic = (char *)buf;
+    if (*(bufend - 1) != 0)
+	return( -1 );
 
     ir_debug( Dmsg(10, "req->mode =%d\n", Request.type21.mode) );
